package luke.core.utils;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.swing.SwingUtilities;

// 导入日志工具类
import luke.core.logging.LogUtil;
import luke.core.config.AppDataManager;

/**
 * 播放状态管理器
 * 用于统一管理播放状态，支持观察者模式，一处更新多处响应
 */
public class PlaybackStateManager {
    // 单例实例
    private static PlaybackStateManager instance;

    private float volume = 1.0f;

    public float getVolume() {
        return volume;
    }

    public void setVolume(float volume) {
        this.volume = volume;
    }

    // 节拍音量(0.0-1.0)
    private float beatVolume = 1.0f;

    public float getBeatVolume() {
        return beatVolume;
    }

    public void setBeatVolume(float beatVolume) {
        this.beatVolume = beatVolume;
    }

    // 节拍音效类型(0: 默认快板声, 1: 气泡声, 2: 鼓声, 3: 钢琴声)
    private int beatSoundType = 0;

    public int getBeatSoundType() {
        return beatSoundType;
    }

    public void setBeatSoundType(int beatSoundType) {
        this.beatSoundType = beatSoundType;
    }

    // 背景音量(0.0-1.0)
    private float backgroundVolume = 1.0f;

    public float getBackgroundVolume() {
        return backgroundVolume;
    }

    public void setBackgroundVolume(float backgroundVolume) {
        this.backgroundVolume = backgroundVolume;
        // 同时保存到AppDataManager
        AppDataManager appDataManager = AppDataManager.getInstance();
        appDataManager.setBackgroundVolume(backgroundVolume);
    }

    // 播放状态
    private boolean isPlaying = false;// 播放状态
    private long currentPositionMs = 0; // 当前播放位置（毫秒）
    private long totalDurationMs = 0;   // 总时长（毫秒）
    
    // 音频文件信息
    private File currentFile = null;// 当前播放文件

    private String notifyErrorMsg = "";
    
    // BPM和节拍信息
    private double bpm = 0.0;
    private int beatOffset = 0; // 节拍偏移（毫秒）
    
    // 鼓点启用状态
    private boolean beatEnabled = false;
    
    // 鼓点线条可见性状态
    private boolean beatLinesVisible = true;
    
    // 保存成功状态
    private boolean saveSuccessful = false;
    
    // 去除抖音视频结尾音状态
    private boolean removeDouyinEndingSound = true; // 默认勾选
    
    // 观察者列表
    private List<PlaybackStateListener> playbackStateListeners = new ArrayList<>();
    private List<MetadataListener> metadataListeners = new ArrayList<>();
    private List<BeatEnableListener> beatEnableListeners = new ArrayList<>();
    private List<SaveSuccessListener> saveSuccessListeners = new ArrayList<>();
    private List<RemoveDouyinEndingSoundListener> removeDouyinEndingSoundListeners = new ArrayList<>();
    private List<BeatLinesVisibilityListener> beatLinesVisibilityListeners = new ArrayList<>();
    
    /**
     * 私有构造函数，防止外部实例化
     */
    private PlaybackStateManager() {}
    
    /**
     * 获取单例实例
     * 
     * @return PlaybackStateManager实例
     */
    public static synchronized PlaybackStateManager getInstance() {
        if (instance == null) {
            instance = new PlaybackStateManager();
        }
        return instance;
    }
    
    /**
     * 添加状态监听器
     * 
     * @param listener 状态监听器
     */
    public void addListener(PlaybackStateListener listener) {
        if (!playbackStateListeners.contains(listener)) {
            playbackStateListeners.add(listener);
        }
    }
    
    /**
     * 添加元数据监听器
     * 
     * @param listener 元数据监听器
     */
    public void addListener(MetadataListener listener) {
        if (!metadataListeners.contains(listener)) {
            metadataListeners.add(listener);
        }
    }
    
    /**
     * 添加鼓点启用状态监听器
     * 
     * @param listener 鼓点启用状态监听器
     */
    public void addListener(BeatEnableListener listener) {
        if (!beatEnableListeners.contains(listener)) {
            beatEnableListeners.add(listener);
        }
    }
    
    /**
     * 添加保存成功状态监听器
     * 
     * @param listener 保存成功状态监听器
     */
    public void addListener(SaveSuccessListener listener) {
        if (!saveSuccessListeners.contains(listener)) {
            saveSuccessListeners.add(listener);
        }
    }
    
    /**
     * 添加去除抖音视频结尾音状态监听器
     * 
     * @param listener 去除抖音视频结尾音状态监听器
     */
    public void addListener(RemoveDouyinEndingSoundListener listener) {
        if (!removeDouyinEndingSoundListeners.contains(listener)) {
            removeDouyinEndingSoundListeners.add(listener);
        }
    }
    
    /**
     * 添加鼓点线条可见性监听器
     * 
     * @param listener 鼓点线条可见性监听器
     */
    public void addListener(BeatLinesVisibilityListener listener) {
        if (!beatLinesVisibilityListeners.contains(listener)) {
            beatLinesVisibilityListeners.add(listener);
        }
    }
    
    /**
     * 设置总时长
     * 
     * @param durationMs 总时长（毫秒）
     */
    public void setTotalDurationMs(long durationMs) {
        this.totalDurationMs = durationMs;
        // 通知所有监听器总时长已更新
        notifyDurationChange();
    }
    
    /**
     * 设置BPM信息
     * 
     * @param bpm BPM值
     */
    public void setBpm(double bpm) {
        this.bpm = bpm;
        // 通知所有监听器BPM已更新
        notifyBpmChange();
    }
    
    /**
     * 设置节拍偏移
     * 
     * @param offset 节拍偏移（毫秒）
     */
    public void setBeatOffset(int offset) {
        this.beatOffset = offset;
        
        // 通知所有监听器节拍偏移已更新
        notifyBeatOffsetChange();
    }
    
    /**
     * 设置鼓点启用状态
     * 
     * @param enabled 鼓点是否启用
     */
    public void setBeatEnabled(boolean enabled) {
        this.beatEnabled = enabled;
        
        // 通知所有监听器鼓点启用状态已更新
        notifyBeatEnabledChange();
    }
    
    /**
     * 设置鼓点线条可见性
     * 
     * @param visible 鼓点线条是否可见
     */
    public void setBeatLinesVisible(boolean visible) {
        this.beatLinesVisible = visible;
        
        // 通知所有监听器鼓点线条可见性已更新
        notifyBeatLinesVisibilityChange();
    }
    
    /**
     * 设置保存成功状态
     * 
     * @param successful 保存是否成功
     */
    public void setSaveSuccessful(boolean successful) {
        this.saveSuccessful = successful;
        
        // 通知所有监听器保存成功状态已更新
        notifySaveSuccessChange();
    }
    
    /**
     * 设置去除抖音视频结尾音状态
     * 
     * @param remove 是否去除抖音视频结尾音
     */
    public void setRemoveDouyinEndingSound(boolean remove) {
        LogUtil.debug("PlaybackStateManager", "setRemoveDouyinEndingSound", "设置去除抖音视频结尾音状态: " + remove);
        this.removeDouyinEndingSound = remove;
        
        // 通知所有监听器去除抖音视频结尾音状态已更新
        notifyRemoveDouyinEndingSoundChange();
    }
    
    /**
     * 通知所有监听器播放状态已更新（异步）
     */
    private void notifyStateChange() {
        SwingUtilities.invokeLater(() -> {
            for (PlaybackStateListener listener : playbackStateListeners) {
                listener.onPlaybackStateChanged(isPlaying);
            }
        });
    }
    
    /**
     * 通知所有监听器位置已更新（异步）
     */
    private void notifyPositionChange() {
        SwingUtilities.invokeLater(() -> {
            for (PlaybackStateListener listener : playbackStateListeners) {
                listener.onPositionChanged(currentPositionMs);
            }
        });
    }
    
    /**
     * 通知所有监听器总时长已更新（异步）
     */
    private void notifyDurationChange() {
        SwingUtilities.invokeLater(() -> {
            for (PlaybackStateListener listener : playbackStateListeners) {
                listener.onDurationChanged(totalDurationMs);
            }
        });
    }
    
    /**
     * 通知所有监听器文件已更新（异步）
     */
    private void notifyFileChange() {
        SwingUtilities.invokeLater(() -> {
            for (PlaybackStateListener listener : playbackStateListeners) {
                listener.onFileChanged(currentFile);
            }
        });
    }
    
    /**
     * 通知所有监听器BPM已更新（异步）
     */
    private void notifyBpmChange() {
        SwingUtilities.invokeLater(() -> {
            for (MetadataListener listener : metadataListeners) {
                listener.onBpmChanged(bpm);
            }
        });
    }
    
    /**
     * 通知所有监听器节拍偏移已更新（异步）
     */
    private void notifyBeatOffsetChange() {
        SwingUtilities.invokeLater(() -> {
            for (MetadataListener listener : metadataListeners) {
                listener.onBeatOffsetChanged(beatOffset);
            }
        });
    }
    
    /**
     * 通知所有监听器鼓点启用状态已更新（异步）
     */
    private void notifyBeatEnabledChange() {
        SwingUtilities.invokeLater(() -> {
            for (BeatEnableListener listener : beatEnableListeners) {
                listener.onBeatEnabledChanged(beatEnabled);
            }
        });
    }
    
    /**
     * 通知所有监听器鼓点线条可见性已更新（异步）
     */
    private void notifyBeatLinesVisibilityChange() {
        SwingUtilities.invokeLater(() -> {
            for (BeatLinesVisibilityListener listener : beatLinesVisibilityListeners) {
                listener.onBeatLinesVisibilityChanged(beatLinesVisible);
            }
        });
    }
    
    /**
     * 通知所有监听器保存成功状态已更新（异步）
     */
    private void notifySaveSuccessChange() {
        SwingUtilities.invokeLater(() -> {
            for (SaveSuccessListener listener : saveSuccessListeners) {
                listener.onSaveSuccessChanged(saveSuccessful);
            }
        });
    }
    
    /**
     * 通知所有监听器去除抖音视频结尾音状态已更新（异步）
     */
    private void notifyRemoveDouyinEndingSoundChange() {
        SwingUtilities.invokeLater(() -> {
            for (RemoveDouyinEndingSoundListener listener : removeDouyinEndingSoundListeners) {
                listener.onRemoveDouyinEndingSoundChanged(removeDouyinEndingSound);
            }
        });
    }
    
    /**
     * 获取当前是否正在播放
     * 
     * @return 是否正在播放
     */
    public boolean isPlaying() {
        return isPlaying;
    }
    
    /**
     * 获取当前播放位置
     * 
     * @return 播放位置（毫秒）
     */
    public long getCurrentPositionMs() {
        return currentPositionMs;
    }
    
    /**
     * 获取总时长
     * 
     * @return 总时长（毫秒）
     */
    public long getTotalDurationMs() {
        return totalDurationMs;
    }
    
    /**
     * 获取当前播放文件
     * 
     * @return 当前播放文件
     */
    public File getCurrentFile() {
        return currentFile;
    }
    
    /**
     * 获取BPM
     * 
     * @return BPM值
     */
    public double getBpm() {
        return bpm;
    }
    
    /**
     * 获取节拍偏移
     * 
     * @return 节拍偏移（毫秒）
     */
    public int getBeatOffset() {
        return beatOffset;
    }
    
    /**
     * 获取鼓点是否启用
     * 
     * @return 鼓点是否启用
     */
    public boolean isBeatEnabled() {
        return beatEnabled;
    }
    
    /**
     * 获取鼓点线条是否可见
     * 
     * @return 鼓点线条是否可见
     */
    public boolean isBeatLinesVisible() {
        return beatLinesVisible;
    }
    
    /**
     * 获取保存是否成功
     * 
     * @return 保存是否成功
     */
    public boolean isSaveSuccessful() {
        return saveSuccessful;
    }
    
    /**
     * 获取是否去除抖音视频结尾音
     * 
     * @return 是否去除抖音视频结尾音
     */
    public boolean isRemoveDouyinEndingSound() {
        return removeDouyinEndingSound;
    }

    /**
     *  获取播放位置（毫秒）
     * @return
     */
    public long getPlaybackPositionMs() {
        return currentPositionMs;
    }

    public void setCurrentPositionMs(long currentPositionMs) {
        this.currentPositionMs = currentPositionMs;
        notifyPositionChange();
    }

    public void setCurrentFile(File currentFile) {
        this.currentFile = currentFile;
        notifyFileChange();
    }

    public void setIsPlaying(boolean isPlaying) {
        this.isPlaying = isPlaying;
        notifyStateChange();
    }

    public void setNotifyErrorMsg(String s) {
        this.notifyErrorMsg = s;
    }


    
    /**
     * 播放状态监听器接口 - 只包含播放状态相关方法
     */
    public interface PlaybackStateListener {
        /**
         * 当播放状态改变时调用
         * 
         * @param isPlaying 是否正在播放
         */
        default void onPlaybackStateChanged(boolean isPlaying) {}
        
        /**
         * 当播放位置改变时调用
         * 
         * @param positionMs 播放位置（毫秒）
         */
        default void onPositionChanged(long positionMs) {}
        
        /**
         * 当总时长改变时调用
         * 
         * @param durationMs 总时长（毫秒）
         */
        default void onDurationChanged(long durationMs) {}
        
        /**
         * 当播放文件改变时调用
         * 
         * @param file 播放文件
         */
        default void onFileChanged(File file) {}
    }
    
    /**
     * 元数据监听器接口 - 包含BPM、偏移量等元数据相关方法
     */
    public interface MetadataListener {
        /**
         * 当BPM改变时调用
         * 
         * @param bpm BPM值
         */
        default void onBpmChanged(double bpm) {}
        
        /**
         * 当节拍偏移改变时调用
         * 
         * @param offset 节拍偏移（毫秒）
         */
        default void onBeatOffsetChanged(int offset) {}
    }
    
    /**
     * 鼓点启用状态监听器接口 - 包含鼓点启用状态相关方法
     */
    public interface BeatEnableListener {
        /**
         * 当鼓点启用状态改变时调用
         * 
         * @param enabled 鼓点是否启用
         */
        default void onBeatEnabledChanged(boolean enabled) {}
    }
    
    /**
     * 保存成功状态监听器接口 - 包含保存成功状态相关方法
     */
    public interface SaveSuccessListener {
        /**
         * 当保存成功状态改变时调用
         * 
         * @param successful 保存是否成功
         */
        default void onSaveSuccessChanged(boolean successful) {}
    }
    
    /**
     * 去除抖音视频结尾音状态监听器接口 - 包含去除抖音视频结尾音状态相关方法
     */
    public interface RemoveDouyinEndingSoundListener {
        /**
         * 当去除抖音视频结尾音状态改变时调用
         * 
         * @param enabled 去除抖音视频结尾音是否启用
         */
        default void onRemoveDouyinEndingSoundChanged(boolean enabled) {}
    }
    
    /**
     * 鼓点线条可见性监听器接口 - 包含鼓点线条可见性相关方法
     */
    public interface BeatLinesVisibilityListener {
        /**
         * 当鼓点线条可见性改变时调用
         * 
         * @param visible 鼓点线条是否可见
         */
        default void onBeatLinesVisibilityChanged(boolean visible) {}
    }
}